package top.callname.service.impl;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.weixin4j.Weixin;
import org.weixin4j.WeixinException;
import org.weixin4j.component.MessageComponent;

import top.callname.bean.ClassBean;
import top.callname.bean.ConstanstBean;
import top.callname.bean.NoticeBean;
import top.callname.bean.NoticePageList;
import top.callname.bean.RspInfoBean;
import top.callname.bean.StudentBean;
import top.callname.dao.ClassDao;
import top.callname.dao.NoticeDao;
import top.callname.dao.StudentDao;
import top.callname.service.NoticeService;
import top.callname.util.DateUtil;

public class NoticeServiceImpl implements NoticeService{

	private final NoticeDao noticeDao = new NoticeDao();
	private final ClassDao classDao = new ClassDao();
	private final StudentDao studentDao = new StudentDao();
	private Logger logger = Logger.getLogger(this.getClass());
	
	@Override
	public NoticePageList getListByPid(int pageNow, Integer pid) {
		NoticePageList pageList = noticeDao.selectPageByPid(pageNow, pid);
		if(pageList.getList().size()>0){
			for (int i = 0; i < pageList.getList().size(); i++) {
				NoticeBean bean = pageList.getList().get(i);
				String classNames = getClassNamesByCids(bean.getCids());
				pageList.getList().get(i).setClassNames(classNames);
			}
			pageList.setRspCode(ConstanstBean.RSP_SUCCESS);
			pageList.setRspDesc("查询公告记录："+pageList.getList().size()+" 条记录！");
		}
		return pageList;
	}

	private String getClassNamesByCids(String cids){
		List<ClassBean> students = classDao.selectByCids(cids);
		String classNames = "";
		for (int i = 0; i < students.size(); i++) {
			if(i==students.size()-1){
				classNames += students.get(i).getClassName();
			}else{
				classNames += students.get(i).getClassName()+"，";
			}
		}
		return classNames;
	}

	@Override
	public RspInfoBean addNoticeTask(NoticeBean noticeBean) {
		noticeBean.setStatus(ConstanstBean.STATUS_FALSE);
		RspInfoBean rsp = new RspInfoBean();
		if(noticeBean.getContent()==null || "".equals(noticeBean.getContent().trim())){
			rsp.setRspCode(ConstanstBean.RSP_FAULT);
			rsp.setRspDesc("公告内容不得为空！");
			return rsp;
		}
		if(noticeBean.getSendTime()==null || "".equals(noticeBean.getSendTime().trim())){
			rsp.setRspCode(ConstanstBean.RSP_FAULT);
			rsp.setRspDesc("发送时间不得为空！");
			return rsp;
		}
		if(noticeBean.getCids()==null || "".equals(noticeBean.getCids().trim())){
			rsp.setRspCode(ConstanstBean.RSP_FAULT);
			rsp.setRspDesc("必须指定发送的班级！");
			return rsp;
		}
		boolean f = noticeDao.insertNotice(noticeBean);
		if(f){
			rsp.setRspDesc("公告任务创建成功！");
		}else{
			rsp.setRspDesc("公告任务创建失败！");
			rsp.setRspCode(ConstanstBean.RSP_FAULT);
		}
		logger.debug("创建公告任务："+rsp.toString());
		return rsp;
	}

	@Override
	public RspInfoBean addNoticeAndSend(NoticeBean noticeBean) {
		RspInfoBean rsp = new RspInfoBean();
		if(noticeBean.getContent()==null || "".equals(noticeBean.getContent().trim())){
			rsp.setRspCode(ConstanstBean.RSP_FAULT);
			rsp.setRspDesc("公告内容不得为空！");
			return rsp;
		}
		if(noticeBean.getCids()==null || "".equals(noticeBean.getCids().trim())){
			rsp.setRspCode(ConstanstBean.RSP_FAULT);
			rsp.setRspDesc("必须指定发送的班级！");
			return rsp;
		}
		noticeBean.setSendTime(DateUtil.dateToStrLong(new Date()));
		noticeBean.setStatus(ConstanstBean.STATUS_FALSE);
		boolean f = noticeDao.insertNotice(noticeBean);
		if(f){
			rsp.setRspDesc("公告任务创建成功！");
			/*//发送消息
			List<NoticeBean> notices = new ArrayList<NoticeBean>();
			notices.add(noticeBean);
			sendMessage(notices);*/
		}else{
			rsp.setRspCode(ConstanstBean.RSP_FAULT);
			rsp.setRspDesc("公告任务创建失败！");
		}
		logger.debug("创建公告任务："+rsp.toString());
		return rsp;
	}

	@Override
	public void sendNoticeTask() {
		
		/**
		 * 查询所有未处理的公告
		 */
		 List<NoticeBean> notices = noticeDao.selectListByStatus(ConstanstBean.STATUS_FALSE);
		 sendMessage(notices);
	}
	
	private void sendMessage(List<NoticeBean> notices){
		 if(notices!=null && notices.size()>0){
			 notices = filterNoticeList(notices);
			 logger.info("开始群发消息，共有 "+notices.size()+" 条消息准备群发！");
			 for (NoticeBean notice : notices) {
				 List<StudentBean> students = studentDao.selectBindedStudentByCids(notice.getCids());
				 logger.info("本条消息将发送给："+students.size()+" 位用户！");
				 if(students.size()>0){
					 Weixin weixin = new Weixin();
					 MessageComponent commont = new MessageComponent(weixin);
					 try {
						logger.info("开始发送消息："+notice.getContent());
						commont.massSendContent(getStudentOpenids(students) , notice.getContent()) ;
					} catch (WeixinException e) {
						logger.error("发送消息出错："+e);
					}
				 }
				 if(notice.getId()!=null){
					 noticeDao.updateNoticeStatus(notice.getId());
				 }
			}
		 }
	}
	
	
	private String[] getStudentOpenids(List<StudentBean> students){
		String  openids[] = null;
		int index = 0;
		 if(students.size()>0){
			 openids = new String[students.size()];
			 for (StudentBean obj : students) {
				 openids[index++] = obj.getOpenid();
			}
		 }
		 logger.info("查询到"+openids.length+"条用户!");
		 return openids;
	}
	
	/**
	 * 过滤要执行发送的公告,当前任务的执行时间和当前时间比较在 1分钟以内的 ，都要发送出去
	 * @return  List<NoticeBean>
	 * @throws ParseException 
	 */
	public List<NoticeBean> filterNoticeList(List<NoticeBean> notices) {
		List<NoticeBean> filters = new ArrayList<NoticeBean>();
		long now = System.currentTimeMillis();
		long oneMins = 60 * 1000;
		for (NoticeBean notice : notices) {
			long sendTime;
			try {
				sendTime = DateUtil.dateToStamp(notice.getSendTime());
				if(Math.abs(now-sendTime)<=oneMins){
					filters.add(notice);
				}
			} catch (ParseException e) {
				logger.error("时间转换错误："+e);
			}
		}
		return filters;
	}

	@Override
	public NoticeBean getNewNoticeByCid(Integer cid) {
		return noticeDao.selectNewNoticeByCid(cid);
	}

	@Override
	public RspInfoBean closeNotice(Integer id) {
		RspInfoBean rsp = new RspInfoBean();
		noticeDao.updateNoticeStatus(id);
		rsp.setRspCode(ConstanstBean.RSP_SUCCESS);
		return rsp;
	}

	@Override
	public RspInfoBean deleteNotice(Integer id) {
		RspInfoBean rsp = new RspInfoBean();
		boolean f = noticeDao.deleteById(id);
		if(f){
			rsp.setRspCode(ConstanstBean.RSP_SUCCESS);
		}else{
			rsp.setRspCode(ConstanstBean.RSP_FAULT);
			rsp.setRspDesc("公告删除失败！");
		}
		return rsp;
	}
	
	
}
